package co.yixiang.yshop.module.product.service.shippingtemplates;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplatesfree.ShippingTemplatesFreeDO;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplatesregion.ShippingTemplatesRegionDO;
import co.yixiang.yshop.module.product.service.shippingtemplates.dto.*;
import co.yixiang.yshop.module.product.service.shippingtemplatesfree.ShippingTemplatesFreeService;
import co.yixiang.yshop.module.product.service.shippingtemplatesregion.ShippingTemplatesRegionService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.util.*;

import co.yixiang.yshop.module.product.controller.admin.shippingtemplates.vo.*;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplates.ShippingTemplatesDO;
import co.yixiang.yshop.framework.common.pojo.PageResult;

import co.yixiang.yshop.module.product.convert.shippingtemplates.ShippingTemplatesConvert;
import co.yixiang.yshop.module.product.dal.mysql.shippingtemplates.ShippingTemplatesMapper;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.product.enums.ErrorCodeConstants.*;

/**
 * 运费模板 Service 实现类
 *
 * @author yshop
 */
@Service
@Validated
public class ShippingTemplatesServiceImpl extends ServiceImpl<ShippingTemplatesMapper, ShippingTemplatesDO> implements ShippingTemplatesService {

    @Resource
    private ShippingTemplatesMapper shippingTemplatesMapper;
    @Resource
    private ShippingTemplatesRegionService shippingTemplatesRegionService;
    @Resource
    private ShippingTemplatesFreeService shippingTemplatesFreeService;

    @Override
    public Integer createShippingTemplates(ShippingTemplatesCreateReqVO createReqVO) {
        // 插入
        ShippingTemplatesDO shippingTemplates = ShippingTemplatesConvert.INSTANCE.convert(createReqVO);
        shippingTemplatesMapper.insert(shippingTemplates);
        // 返回
        return shippingTemplates.getId();
    }

    @Override
    public void updateShippingTemplates(ShippingTemplatesUpdateReqVO updateReqVO) {
        // 校验存在
        validateShippingTemplatesExists(updateReqVO.getId());
        // 更新
        ShippingTemplatesDO updateObj = ShippingTemplatesConvert.INSTANCE.convert(updateReqVO);
        shippingTemplatesMapper.updateById(updateObj);
    }

    @Override
    public void deleteShippingTemplates(Integer id) {
        // 校验存在
        validateShippingTemplatesExists(id);
        // 删除
        shippingTemplatesMapper.deleteById(id);
    }

    private void validateShippingTemplatesExists(Integer id) {
        if (shippingTemplatesMapper.selectById(id) == null) {
            throw exception(SHIPPING_TEMPLATES_NOT_EXISTS);
        }
    }

    @Override
    public ShippingTemplatesDO getShippingTemplates(Integer id) {
        return shippingTemplatesMapper.selectById(id);
    }

    @Override
    public List<ShippingTemplatesDO> getShippingTemplatesList(Collection<Integer> ids) {
        return shippingTemplatesMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ShippingTemplatesDO> getShippingTemplatesPage(ShippingTemplatesPageReqVO pageReqVO) {
        return shippingTemplatesMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ShippingTemplatesDO> getShippingTemplatesList(ShippingTemplatesExportReqVO exportReqVO) {
        return shippingTemplatesMapper.selectList(exportReqVO);
    }

    /**
     * 新增与更新模板
     *
     * @param id                   模板id
     * @param shippingTemplatesDto ShippingTemplatesDto
     */
    @Override
    public void addAndUpdate(Integer id, ShippingTemplatesDTO shippingTemplatesDto) {
        if (ShopCommonEnum.ENABLE.getValue().equals(shippingTemplatesDto.getAppoint())
                && shippingTemplatesDto.getAppointInfo().isEmpty()) {
            throw exception(SHIPPING_TEMPLATES_FREE_NEED);
        }
        ShippingTemplatesDO shippingTemplates = new ShippingTemplatesDO();
        BeanUtil.copyProperties(shippingTemplatesDto, shippingTemplates);
        shippingTemplates.setRegionInfo(JSON.toJSONString(shippingTemplatesDto.getRegionInfo()));
        shippingTemplates.setAppointInfo(JSON.toJSONString(shippingTemplatesDto.getAppointInfo()));
        if (id != null && id > 0) {
            shippingTemplates.setId(id);
            this.updateById(shippingTemplates);
        } else {
            this.save(shippingTemplates);
        }

        this.saveRegion(shippingTemplatesDto, shippingTemplates.getId());
        this.saveFreeReigion(shippingTemplatesDto, shippingTemplates.getId());
    }

    /**
     * 保存模板设置的区域价格
     *
     * @param yxShippingTemplates ShippingTemplatesDTO
     * @param tempId              运费模板id
     */
    private void saveRegion(ShippingTemplatesDTO yxShippingTemplates, Integer tempId) {
        Long count = shippingTemplatesRegionService.count(Wrappers
                .<ShippingTemplatesRegionDO>lambdaQuery()
                .eq(ShippingTemplatesRegionDO::getTempId, tempId));
        if (count > 0) {
            shippingTemplatesRegionService.remove(Wrappers
                    .<ShippingTemplatesRegionDO>lambdaQuery()
                    .eq(ShippingTemplatesRegionDO::getTempId, tempId));
        }

        List<ShippingTemplatesRegionDO> shippingTemplatesRegions = new ArrayList<>();


        List<RegionInfoDTO> regionInfo = yxShippingTemplates.getRegionInfo();


        for (RegionInfoDTO regionInfoDto : regionInfo) {
            String uni = IdUtil.simpleUUID();
            if (regionInfoDto.getRegion() != null && !regionInfoDto.getRegion().isEmpty()) {
                for (RegionDTO regionDto : regionInfoDto.getRegion()) {
                    if (regionDto.getChildren() != null && !regionDto.getChildren().isEmpty()) {
                        for (RegionChildrenDTO childrenDtp : regionDto.getChildren()) {
                            ShippingTemplatesRegionDO shippingTemplatesRegion = ShippingTemplatesRegionDO.builder()
                                    .tempId(tempId)
                                    .first(new BigDecimal(regionInfoDto.getFirst()))
                                    .firstPrice(new BigDecimal(regionInfoDto.getPrice()))
                                    .continues(new BigDecimal(regionInfoDto.get_continue()))
                                    .continuePrice(new BigDecimal(regionInfoDto.getContinue_price()))
                                    .type(yxShippingTemplates.getType())
                                    .uniqid(uni)
                                    .provinceId(Integer.valueOf(regionDto.getCity_id()))
                                    .cityId(Integer.valueOf(childrenDtp.getCity_id()))
                                    .build();
                            shippingTemplatesRegions.add(shippingTemplatesRegion);
                        }
                    } else {
                        ShippingTemplatesRegionDO shippingTemplatesRegion = ShippingTemplatesRegionDO.builder()
                                .tempId(tempId)
                                .first(new BigDecimal(regionInfoDto.getFirst()))
                                .firstPrice(new BigDecimal(regionInfoDto.getPrice()))
                                .continues(new BigDecimal(regionInfoDto.get_continue()))
                                .continuePrice(new BigDecimal(regionInfoDto.getContinue_price()))
                                .type(yxShippingTemplates.getType())
                                .uniqid(uni)
                                .provinceId(Integer.valueOf(regionDto.getCity_id()))
                                .build();
                        shippingTemplatesRegions.add(shippingTemplatesRegion);
                    }
                }
            }
        }

        if (shippingTemplatesRegions.isEmpty()) {
            throw exception(SHIPPING_TEMPLATES_REGION_NOT_EXISTS);
        }

        shippingTemplatesRegionService.saveBatch(shippingTemplatesRegions);

    }

    /**
     * 保存包邮区域
     *
     * @param yxShippingTemplates ShippingTemplatesDto
     * @param tempId              模板id
     */
    private void saveFreeReigion(ShippingTemplatesDTO yxShippingTemplates, Integer tempId) {

        if (yxShippingTemplates.getAppointInfo() == null
                || yxShippingTemplates.getAppointInfo().isEmpty()) {
            return;
        }

        Long count = shippingTemplatesFreeService.count(Wrappers
                .<ShippingTemplatesFreeDO>lambdaQuery()
                .eq(ShippingTemplatesFreeDO::getTempId, tempId));
        if (count > 0) {
            shippingTemplatesFreeService.remove(Wrappers
                    .<ShippingTemplatesFreeDO>lambdaQuery()
                    .eq(ShippingTemplatesFreeDO::getTempId, tempId));
        }

        List<ShippingTemplatesFreeDO> shippingTemplatesFrees = new ArrayList<>();


        List<AppointInfoDTO> appointInfo = yxShippingTemplates.getAppointInfo();
        for (AppointInfoDTO appointInfoDto : appointInfo) {
            String uni = IdUtil.simpleUUID();

            if (appointInfoDto.getPlace() != null && !appointInfoDto.getPlace().isEmpty()) {
                for (RegionDTO regionDto : appointInfoDto.getPlace()) {
                    if (regionDto.getChildren() != null && !regionDto.getChildren().isEmpty()) {
                        for (RegionChildrenDTO childrenDto : regionDto.getChildren()) {
                            ShippingTemplatesFreeDO shippingTemplatesFree = ShippingTemplatesFreeDO.builder()
                                    .tempId(tempId)
                                    .number(new BigDecimal(appointInfoDto.getA_num()))
                                    .price(new BigDecimal(appointInfoDto.getA_price()))
                                    .type(yxShippingTemplates.getType())
                                    .uniqid(uni)
                                    .provinceId(Integer.valueOf(regionDto.getCity_id()))
                                    .cityId(Integer.valueOf(childrenDto.getCity_id()))
                                    .build();
                            shippingTemplatesFrees.add(shippingTemplatesFree);
                        }
                    }
                }
            }
        }


        if (shippingTemplatesFrees.isEmpty()) {
            throw exception(SHIPPING_TEMPLATES_FREE_NOT_EXISTS);
        }

        shippingTemplatesFreeService.saveBatch(shippingTemplatesFrees);


    }


}
